package com.yjd.comm.util;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import com.yjd.comm.cache.RedisCachUtils;
import com.yjd.comm.enums.CachNameSpaceEnum;
import com.yjd.comm.enums.ExpireTime;

/**
 * 处理短信验证码每小时只能获取三次的验证
 * @author zhoujin
 *
 */
public class MsgHourCountUtils {
	/**
	 * 缓存key
	 */
	private static final String MSG_HOUR_SEND_CACHED_KEY = "hour_send_times";
	
	/**
	 * 一小时内最大发送次数
	 */
	private static final double CAPTCHA_GENARATOE_COUNT = 3;
	
	/**
	 */
	private static final long SECOND_TO_AN_HOUR = 3600;
	
	public static void updateCached(String key) throws Exception {
		Calendar cal = Calendar.getInstance();
		//获取缓存块
		Map<String, Stack<Long>> captchaMap = (Map<String, Stack<Long>>)RedisCachUtils.getCach(CachNameSpaceEnum.MSG_HOUR_SEND_TIMES,MSG_HOUR_SEND_CACHED_KEY);
		// 时间集合
		Stack<Long> statistics = captchaMap==null?null:captchaMap.get(key);
		if (statistics == null || statistics.isEmpty()) {
			captchaMap.put(key, initStack(cal.getTimeInMillis()));
			RedisCachUtils.putCach(CachNameSpaceEnum.MSG_HOUR_SEND_TIMES,MSG_HOUR_SEND_CACHED_KEY,captchaMap,ExpireTime.ONE_HOUR);
			return;
		}
		statistics.add(cal.getTimeInMillis());
		captchaMap.put(key, statistics);
		RedisCachUtils.putCach(CachNameSpaceEnum.MSG_HOUR_SEND_TIMES,MSG_HOUR_SEND_CACHED_KEY,captchaMap,ExpireTime.ONE_HOUR);
	}
	
	/**
	 * 是否一小时内发送三次
	 * @param key
	 * @return boolean 达到最大频率返回true
	 * @throws Exception
	 */
	public static boolean validate(String key,long time) throws Exception {
		//获取缓存块
		Map<String, Stack<Long>> captchaMap = (Map<String, Stack<Long>>)RedisCachUtils.getCach(CachNameSpaceEnum.MSG_HOUR_SEND_TIMES,MSG_HOUR_SEND_CACHED_KEY);
		//获取key对应的缓存
		Stack<Long> statistics = captchaMap==null?null:captchaMap.get(key);
		if (statistics == null || statistics.isEmpty()) {
			return false;
		}
		return countVarible(statistics,time);

	}
	
	private static boolean countVarible(Stack<Long> statistics,long time) {
		//两次以上才需要判断
		if(statistics.isEmpty() || statistics.size()<=2){
			return false;
		}
		int count = 0;
		
		Stack<Long> tempStack = (Stack<Long>) statistics.clone ();
		while (!tempStack.empty()){
			long temp = tempStack.pop()/1000;
			if(time-temp < SECOND_TO_AN_HOUR){
				//如果超过一小时,不需要判断
				count++;
			}
			
			if(count >= CAPTCHA_GENARATOE_COUNT){
				return true;
			}
		}
		return false;
	}

	/**
	 * 初始化队列
	 * 
	 * @param args
	 * @return Stack<Long>
	 * @throws Exception
	 */
	private static Stack<Long> initStack(Long... args) throws Exception {
		Stack<Long> linkedList = new Stack<Long>();
		for (Long temp : args) {
			linkedList.push(temp);
		}
		return linkedList;
	}
	
	/**
	 * 获取缓存块
	* @return Map<String,Stack<Long>>
	* @throws Exception
	 */
	private static Map<String, Stack<Long>> getCaptchaMap(String key) throws Exception {
		Map<String, Stack<Long>> captchaMap = (Map<String, Stack<Long>>)RedisCachUtils.getCach(CachNameSpaceEnum.MSG_HOUR_SEND_TIMES,MSG_HOUR_SEND_CACHED_KEY);
		if (captchaMap == null) {
			captchaMap = new HashMap<String, Stack<Long>>();
		}
		return captchaMap;
	}
	
}
